#include "Platform/OpenGL/OpenGLTextureCube.h"

// #define STB_IMAGE_IMPLEMENTATION
// #include <stb_image/stb_image.h>
#include "openGLTextureCube.h"

namespace CC
{

	OpenGLTextureCube::OpenGLTextureCube(const std::string& path)
        : m_Path(path)
	{
        glGenTextures(1, &m_RendererID);

	}
	OpenGLTextureCube::~OpenGLTextureCube()
	{
		glDeleteTextures(1, &m_RendererID);
	}

    void OpenGLTextureCube::Generate(unsigned int index, unsigned char * data, int width, int height, int channels, TextureType type)
    {
        if (data)
        {
            m_IsLoaded = true;

            m_Width = width;
            m_Height = height;

            GLenum internalFormat = GL_RGB, dataFormat = GL_RGB;
            if (channels == 4)
            {
                internalFormat = GL_RGBA;
                dataFormat = GL_RGBA;
            }

            m_InternalFormat = internalFormat;
            m_DataFormat = dataFormat;

            // glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
            glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererID);
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, m_InternalFormat, width, height, 0, m_DataFormat, GL_UNSIGNED_BYTE, data);

            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

            if (TextureType::TextureType_Repeat == type) {
                glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
            }
            else {
                glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
            }

            glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
        }

    }

	void OpenGLTextureCube::SetData(void *data, uint32_t size)
	{
		uint32_t bpp = m_DataFormat == GL_RGBA ? 4 : 3;
		// HZ_CORE_ASSERT(size == m_Width * m_Height * bpp, "Data must be entire texture!");
		// glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_DataFormat, GL_UNSIGNED_BYTE, data);
	}

	void OpenGLTextureCube::SetData(unsigned char* data, int width, int height, int channels, TextureType type)
	{
	}

	void OpenGLTextureCube::Bind(uint32_t slot) const
	{
		if (m_RendererID == 0)
			return;
		CC_ASSERT(m_RendererID != 0, "ASSERT: OpenGLTextureCube::Bind id=%d\n", m_RendererID);
		glActiveTexture(GL_TEXTURE0 + slot);
		glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererID);
		// glBindTextureUnit(slot, m_RendererID);
	}

	void CC::OpenGLTextureCube::UnBind() const
	{
		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
	}

	void OpenGLTextureCube::SetID(uint32_t id)
	{
		m_RendererID = id;
		CC_CORE_INFO("111111111OpenGLTextureCube::SetID=%d\n", m_RendererID);
	}
}
